#include<iostream>
#include<pthread.h>
#include<semaphore.h>
#include<mutex>
using namespace std;
int curid=0;

class Data
{
public:
    Data(int num1,int num2,int name)
    :_num1(num1),_num2(num2),_name(name)
    {}
public:
    int _num1;
    int _num2;
    int _name;
};

class Func
{
public:
    Func()
    {
        pthread_mutex_init(&mutex,nullptr);
        pthread_cond_init(&cond,nullptr);
    }
    ~Func()
    {
        pthread_mutex_destroy(&mutex);
        pthread_cond_destroy(&cond);
    }
    void Print(Data* d) {
        pthread_mutex_lock(&mutex);
        // 等待轮到当前线程执行
        while (curid != d->_name) {
            pthread_cond_wait(&cond, &mutex);
        }
        
        // 执行打印
        cout << d->_num1 << " ";
        curid = (curid + 1) % 3;
        
        // 唤醒下一个线程
        pthread_cond_broadcast(&cond);
        pthread_mutex_unlock(&mutex);

        pthread_mutex_lock(&mutex);
        // 等待轮到当前线程执行
        while (curid != d->_name) {
            pthread_cond_wait(&cond, &mutex);
        }
        
        // 执行打印
        cout << d->_num2 << " ";
        curid = (curid + 1) % 3;
        
        // 唤醒下一个线程
        pthread_cond_broadcast(&cond);
        pthread_mutex_unlock(&mutex);
    }

    static void* Excute(void* args)
    {
        auto pair = static_cast<std::pair<Func*, Data*>*>(args);
        pair->first->Print(pair->second);
        return nullptr;
    }

    void init() {
        pthread_t threads[3];
        Data* data[3] = {
            new Data(0, 3, 0),
            new Data(1, 4, 1),
            new Data(2, 5, 2)
        };

        for (int i = 0; i < 3; ++i) {
            auto* arg = new pair<Func*, Data*>(this, data[i]);
            pthread_create(&threads[i], nullptr, Excute, arg);
        }

        // 等待所有线程完成
        for (int i = 0; i < 3; ++i) {
            pthread_join(threads[i], nullptr);
        }
    }

private:
    pthread_mutex_t mutex;
    pthread_cond_t cond;
    pthread_t t1;
    pthread_t t2;
    pthread_t t3;
};

int main()
{
    Func().init();
    return 0;
}